package org.newlucene.core.index;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.io.IOException;


import org.newlucene.core.document.Document;
import org.newlucene.core.document.Field;
import org.newlucene.core.store.Directory;
import org.newlucene.core.store.InputStream;
import org.newlucene.core.store.OutputStream;

final class FieldInfos
{
	private List<FieldInfo> byNumber = new ArrayList<FieldInfo>();
	private Map<String, FieldInfo> byName = new HashMap<String, FieldInfo>();

	FieldInfos(Field[] fields)
	{
		addInternal("", 0); // necessary for TermInfosWriter to write the lastTerm, which is initialized to empty string for field name and empty string for field value
		for (Field field : fields)
		{
			addInternal(field.getName(), field.getConfig());
		}
	}
	
	FieldInfos(Directory d) throws IOException
	{
		InputStream input = d.openFile("fields");
		try 
		{
			read(input);
		}
		finally 
		{
			input.close();
		}
	}

	private final void addInternal(String name, int config) 
	{
		FieldInfo fi = new FieldInfo(name, byNumber.size(), config);
		byNumber.add(fi);
		byName.put(name, fi);
	}

	final FieldInfo getFieldInfo(String fieldName) 
	{
		return (FieldInfo)byName.get(fieldName);
	}

	final FieldInfo getFieldInfo(int fieldNumber) 
	{
		return (FieldInfo)byNumber.get(fieldNumber);
	}

	final List<FieldInfo> getFieldInfoList()
	{
		return byNumber;
	}
	
	final int size()
	{
		return byNumber.size();
	}

	final void write(Directory d) throws IOException
	{
		OutputStream output = d.createFile("fields");
		try 
		{
			output.writeVInt(size());
			for (int i = 0; i < size(); i++) 
			{
				FieldInfo fi = getFieldInfo(i);
				output.writeString(fi.name);
				output.writeByte((byte) fi.getFieldConfig());
			}
		}
		finally 
		{
			output.close();
		}
	}

	private final void read(InputStream input) throws IOException 
	{
		int size = input.readVInt();
		for (int i = 0; i < size; i++)
		{
			String s = input.readString().intern();
			byte b = input.readByte();
			addInternal(s, b);
		}
	}
}